package com.atguigu.srb.core.service.impl;

import com.atguigu.common.exception.BusinessException;
import com.atguigu.common.results.ResultCodeEnum;
import com.atguigu.srb.base.utils.JwtUtils;
import com.atguigu.srb.core.pojo.entity.*;
import com.atguigu.srb.core.mapper.BorrowerMapper;
import com.atguigu.srb.core.pojo.vo.BorrowerApprovalVO;
import com.atguigu.srb.core.pojo.vo.BorrowerAttachVo;
import com.atguigu.srb.core.pojo.vo.BorrowerDetailVO;
import com.atguigu.srb.core.pojo.vo.BorrowerVo;
import com.atguigu.srb.core.service.*;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 借款人 服务实现类
 * </p>
 *
 * @author Atguigu
 * @since 2022-10-24
 */
@Service
public class BorrowerServiceImpl extends ServiceImpl<BorrowerMapper, Borrower> implements BorrowerService {
    @Autowired
    BorrowerAttachService borrowerAttachService;
    @Autowired
    UserInfoService userInfoService;
    @Autowired
    DictService dictService;
    @Autowired
    IntegralGradeService integralGradeService;


    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void saveBorrower(BorrowerVo borrowerVo, String token) {
        Long userId = JwtUtils.getUserId(token);
        //保存借款人信息到数据库
        Borrower borrower = new Borrower();
        BeanUtils.copyProperties(borrowerVo , borrower);
        borrower.setUserId(userId);
        //查询借款人本人数据
        UserInfo userInfo = userInfoService.getById(userId);
        borrower.setMobile(userInfo.getMobile());
        borrower.setName(userInfo.getName());
        borrower.setIdCard(userInfo.getIdCard());

        //设置borrower审核状态为已提交：1
        borrower.setStatus(1);

        this.save(borrower);

        //保存借款人附件数据到数据库
        List<BorrowerAttach> attaches = borrowerVo.getBorrowerAttachs();
        if(!CollectionUtils.isEmpty(attaches)){
        //每个附件对象都需要绑定到借款人信息上(借款人id外键关联)
            attaches.forEach(attach->{
                attach.setBorrowerId(borrower.getId());
            });
            borrowerAttachService.saveBatch(attaches);
        }
    }

    @Override
    public Integer getStatus(String token) {
        Long userId = JwtUtils.getUserId(token);
        Integer status = 0;
        //查询当前用户的审核数据
        Borrower borrower = this.getOne(new LambdaQueryWrapper<Borrower>()
                .eq(Borrower::getUserId, userId));
        if(borrower==null){
            //当前用户还未提交借款人认证信息：0前端显示填写信息表单
            return status;
        }
        return borrower.getStatus();
    }

    @Override
    public void listBorrowers(Page<Borrower> page, String key) {
        LambdaQueryWrapper<Borrower> queryWrapper = Wrappers.lambdaQuery();
        if(!StringUtils.isEmpty(key)){
            //使用过滤条件过滤：
            queryWrapper.like(Borrower::getName ,key)
                    .or()
                    .like(Borrower::getIdCard , key)
                    .or()
                    .like(Borrower::getMobile , key);
        }
        //参数1：携带分页条件
        //参数2：携带过滤条件
        this.page(page,queryWrapper);
    }

    @Override
    public BorrowerDetailVO selectBorrowerDetail(String id) {
        //1、根据借款人id查询借款人详情
        Borrower borrower = this.getById(id);
        if(borrower==null){
            throw new BusinessException(ResultCodeEnum.ERROR);
        }
        BorrowerDetailVO vo = new BorrowerDetailVO();
        BeanUtils.copyProperties(borrower , vo);
        //2、将借款人详情中的  数值/状态值 转为对应的字符串(方便前端展示)
        // 根据状态设置字符串
        //0：未认证，1：认证中， 2：认证通过， -1：认证失败
        Integer status = borrower.getStatus();
        switch(status){
            case 0:
                vo.setStatus("未认证");
                break;
            case 1:
                vo.setStatus("认证中");
                break;
            case 2:
                vo.setStatus("认证通过");
                break;
            case -1:
                vo.setStatus("认证失败");
                break;
        }
        vo.setSex(borrower.getSex()==0?"女":"男");
        vo.setMarry(borrower.getMarry()?"是":"否");
        // 将数据字典的value值转为它的标题设置
        //数据字典 使用value值不能确定唯一一行数据，需要使用上一级数据字典的dict_code确定唯一的一个数据字典
        //使用上一级数据字典的id 当做parent_id+ value值 确定唯一的一个二级数据字典
        Integer contactsRelation = borrower.getContactsRelation();//得到的是 数据字典中的一个value值
        String relation = dictService.queryDictNameByDictCodeAndValue("relation", contactsRelation);
        vo.setContactsRelation(relation);
        String education = dictService.queryDictNameByDictCodeAndValue("education",
                borrower.getEducation());
        vo.setEducation(education);
        String income = dictService.queryDictNameByDictCodeAndValue("income",
                borrower.getIncome());
        vo.setIncome(income);
        String industry = dictService.queryDictNameByDictCodeAndValue("industry",
                borrower.getIndustry());
        vo.setIndustry(industry);
        String returnSource = dictService.queryDictNameByDictCodeAndValue("returnSource",
                borrower.getReturnSource());
        vo.setReturnSource(returnSource);

        //3、查询附件集合
        List<BorrowerAttach> borrowerAttaches = borrowerAttachService.list(new LambdaQueryWrapper<BorrowerAttach>()
                .eq(BorrowerAttach::getBorrowerId, borrower.getId()));
        //将附件集合转为 自定义附件vo对象集合
        if(!CollectionUtils.isEmpty(borrowerAttaches)){
            // 将对象集合转为另一个类型的对象的集合
//            borrowerAttaches.stream().map().collect(Collectors.toList())
            List<BorrowerAttachVo> attachVos = borrowerAttaches.stream().map(borrowerAttach -> {
                BorrowerAttachVo borrowerAttachVo = new BorrowerAttachVo();
                borrowerAttachVo.setImageUrl(borrowerAttach.getImageUrl());
                //根据borrowerAttach的imageType  获取type对应的 文件类型的描述文本信息
                //图片类型（idCard1：身份证正面，idCard2：身份证反面，house：房产证，car：车
                String type = null;
                switch(borrowerAttach.getImageType()){
                    case "idCard1":
                        type = "身份证正面";
                        break;
                    case "idCard2":
                        type = "身份证反面";
                        break;
                    case "house":
                        type = "房产信息";
                        break;
                    case "car":
                        type = "车辆信息";
                        break;
                }

                borrowerAttachVo.setImageType(type);
                return borrowerAttachVo;
            }).collect(Collectors.toList());

            vo.setBorrowerAttachVos(attachVos);
        }

        //4、封装为vo对象返回
        return vo;
    }
    @Autowired
    UserIntegralService userIntegralService;
//    @Autowired
//    UserInfoService userInfoService;
    @Override
    public void approval(BorrowerApprovalVO approvalVO) {
        //1、borrower表：  更新认证状态
        Integer status = approvalVO.getStatus();// 2 -1
        Long borrowerId = approvalVO.getBorrowerId();
        this.update(new LambdaUpdateWrapper<Borrower>()
                .eq(Borrower::getId , borrowerId)
                .set(Borrower::getStatus , status));
        //获取借款人 的用户  id
        Borrower borrower = this.getById(borrowerId);
        Long userId = borrower.getUserId();
        Integer jifen = 0;
        if(status==2){//通过审核才计算积分设置
            //2、一个用户的不同的方式获取的积分 每一个都单独对应user_integral数据
            // 以后积分控制时，不同方式生成的积分 过期时间、生效时间、作用范围都不相同
            Integer infoIntegral = approvalVO.getInfoIntegral();//基本信息积分
            UserIntegral userIntegral = new UserIntegral();
            jifen = infoIntegral;
            userIntegral.setIntegral(infoIntegral);
            userIntegral.setUserId(userId);
            userIntegral.setContent("基本认证信息");
            userIntegralService.save(userIntegral);


            Boolean isIdCardOk = approvalVO.getIsIdCardOk();
            if(isIdCardOk){
                Integer idCardIntegral = isIdCardOk?30:0;
                jifen +=idCardIntegral;
                userIntegral = new UserIntegral();
                userIntegral.setIntegral(idCardIntegral);
                userIntegral.setUserId(userId);
                userIntegral.setContent("身份证认证信息");
                userIntegralService.save(userIntegral);
            }
            Boolean isCarOk = approvalVO.getIsCarOk();
            if(isCarOk){
                Integer carIntegral = isCarOk?60:0;
                jifen +=carIntegral;
                userIntegral = new UserIntegral();
                userIntegral.setIntegral(carIntegral);
                userIntegral.setUserId(userId);
                userIntegral.setContent("车辆认证信息");
                userIntegralService.save(userIntegral);
            }
            Boolean isHouseOk = approvalVO.getIsHouseOk();
            if(isHouseOk){
                Integer hourseIntegral = isHouseOk?100:0;
                jifen +=hourseIntegral;
                userIntegral = new UserIntegral();
                userIntegral.setIntegral(hourseIntegral);
                userIntegral.setUserId(userId);
                userIntegral.setContent("房产认证信息");
                userIntegralService.save(userIntegral);
            }

        }
        //3、user_info表中： 更新借款人认证状态+积分
        userInfoService.update(new LambdaUpdateWrapper<UserInfo>()
            .eq(UserInfo::getId , userId)
            .set(UserInfo::getIntegral , jifen)
            .set(UserInfo::getBorrowAuthStatus , status));

    }

    @Override
    public BigDecimal getBorrowerAmount(String token) {
        //1、获取userId
        Long userId = JwtUtils.getUserId(token);
        //2、查询user_info表中查询会员的 积分:
        // 用户账户不能是禁用状态、判断用户是否绑定了汇付宝账户、判断用户是否提交借款人信息并审核他通过
        UserInfo userInfo = userInfoService.getById(userId);
        //账户被锁定，不能借款
        if(userInfo.getStatus()==0){
            throw new BusinessException(ResultCodeEnum.LOGIN_LOKED_ERROR);
        }
        //账户未绑定汇付宝账号
        if(userInfo.getBindStatus()!=1){
            throw new BusinessException(ResultCodeEnum.USER_NO_BIND_ERROR);
        }
        if(userInfo.getBorrowAuthStatus()!=2){
            throw new BusinessException(ResultCodeEnum.USER_NO_AMOUNT_ERROR);
        }
        //3、根据积分查询允许借款的额度
        //查询用户积分
        Integer integral = userInfo.getIntegral();
        //每个区间都是唯一的
        //  integral_start<=integral and integral_end>=integral
        IntegralGrade integralGrade = integralGradeService.getOne(new LambdaQueryWrapper<IntegralGrade>()
                .le(IntegralGrade::getIntegralStart, integral)
                .ge(IntegralGrade::getIntegralEnd, integral)
                .last("limit 1"));
        if(integralGrade==null){
            //查询不到该用户积分的区间，返回允许的借款额度为0
            return new BigDecimal("0");
        }
        //返回积分区间允许的借款额度
        return integralGrade.getBorrowAmount();
    }
}
